﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using EPiServer;
using EPiServer.Core;
using EPiServer.DataAccess;
using EPiServer.Security;
using EPiServer.Tests.UnitTests;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using PageTypeBuilder;
using TemplateFoundation.Configuration;
using TemplateFoundation.Core;
using TemplateFoundation.PageTypes;
using TemplateFoundation.Tests.Environment;
using TemplateFoundation.Tests.PageTypes;

namespace TemplateFoundation.Tests.UnitTests.TemplateFoundation.Configuration
{
    [TestClass]
    public class SiteSettings : EPiServerUnitTest
    {
        [TestMethod]
        [TestCategory("Site settings")]
        [Description("Creates a new news container, sets it as the news container for the site and then verifies the configuration")]
        public void CreateNewsContainerAndSetSiteSetting()
        {
            // Create container
            PageReference container = null;

            try
            {
                container = PageStructure.CreateNewsContainer("Our news");
            }
            catch
            {
                Assert.Fail("Unable to create news container page");
            }

            // Set site setting
            try
            {
                var startPageEdit = (StartPageBase)PageFactory.Instance.GetStartPage().CreateWritableClone();
                startPageEdit.NewsContainer = container;
                startPageEdit.Save(SaveAction.Publish | SaveAction.ForceCurrentVersion, AccessLevel.NoAccess);
            }
            catch (Exception)
            {
                Assert.Fail("Unable to set news container site setting");
            }

            // Verify site setting
            Assert.IsTrue(container.ID==Settings.Instance.NewsContainer.ID, "News container site setting did not equal newly created container");
        }

        [TestMethod]
        [TestCategory("Site settings")]
        public void VerifyPageTypeIdSettingCanBeSetAndRetrieved()
        {
            var articlePageTypeId = PageTypeResolver.Instance.GetPageTypeID(typeof (ArticlePage));

            if (!articlePageTypeId.HasValue)
            {
                throw new EPiServerTestException("Unable to get ArticlePage page type ID");
            }

            Settings.Instance.ArticlePageTypeId = null;

            Assert.IsNull(Settings.Instance.ArticlePageTypeId, "Unable to set ArticlePageTypeId setting");

            Settings.Instance.ArticlePageTypeId = articlePageTypeId.Value;

            Assert.AreEqual(Settings.Instance.ArticlePageTypeId.Value, articlePageTypeId, "Unable to set ArticlePageTypeId setting");
        }

        [TestMethod]
        [TestCategory("Site settings")]
        public void VerifyNewsDateFolderPageTypeIdSettingCanBeSetAndRetrieved()
        {
            var pageTypeId = PageTypeResolver.Instance.GetPageTypeID(typeof(NewsContainerPage));

            if (!pageTypeId.HasValue)
            {
                throw new EPiServerTestException("Unable to get NewsContainerPage page type ID");
            }

            Settings.Instance.DateFolderPageTypeId = null;

            Assert.IsNull(Settings.Instance.DateFolderPageTypeId, "Unable to set DateFolderPageTypeId setting to null");

            Settings.Instance.DateFolderPageTypeId = pageTypeId.Value;

            Assert.AreEqual(Settings.Instance.DateFolderPageTypeId.Value, pageTypeId, "Unable to set DateFolderPageTypeId setting");
        }

        [TestMethod]
        [TestCategory("Site settings")]
        public void VerifyPersonPageTypeIdSettingCanBeSetAndRetrieved()
        {
            var pageTypeId = PageTypeResolver.Instance.GetPageTypeID(typeof(PersonPage));

            if (!pageTypeId.HasValue)
            {
                throw new EPiServerTestException("Unable to get PersonPage page type ID");
            }

            Settings.Instance.PersonPageTypeId = null;

            Assert.IsNull(Settings.Instance.PersonPageTypeId, "Unable to set PersonPageTypeId setting to null");

            Settings.Instance.PersonPageTypeId = pageTypeId.Value;

            Assert.AreEqual(Settings.Instance.PersonPageTypeId.Value, pageTypeId, "Unable to set PersonPageTypeId setting");
        }

        [TestMethod]
        [TestCategory("Site settings")]
        public void VerifyStandardPageTypeIdSettingCanBeSetAndRetrieved()
        {
            var pageTypeId = PageTypeResolver.Instance.GetPageTypeID(typeof(StandardPage));

            if (!pageTypeId.HasValue)
            {
                throw new EPiServerTestException("Unable to get StandardPageTypeId page type ID");
            }

            Settings.Instance.StandardPageTypeId = null;

            Assert.IsNull(Settings.Instance.StandardPageTypeId, "Unable to set StandardPageTypeId setting to null");

            Settings.Instance.StandardPageTypeId = pageTypeId.Value;

            Assert.AreEqual(Settings.Instance.StandardPageTypeId.Value, pageTypeId, "Unable to set StandardPageTypeId setting");
        }

        [TestMethod]
        [TestCategory("Site settings")]
        public void VerifyContactsContainerCanBeSetAndRetrieved()
        {
            var container = PageStructure.CreateStandardPages("Contacts", PageReference.RootPage, 1)[0];

            Settings.Instance.ContactsContainer = container.PageLink;

            Assert.IsTrue(Settings.Instance.ContactsContainer.ID==container.PageLink.ID, "Unable to set ContactsContainer setting");

            Settings.Instance.ContactsContainer = null;

            Assert.IsNull(Settings.Instance.ContactsContainer, "Unable to set ContactsContainer to null");
        }

        [TestMethod]
        [TestCategory("Site settings")]
        public void VerifyStaticFilePathCanBeSetAndRetrievedWithEnforcedLeadingAndTrailingSlashes()
        {
            Settings.Instance.StaticFilesPath = "Static";

            Assert.IsTrue(Settings.Instance.StaticFilesPath == "/Static/", "Missing leading and/or trailing slash");

            Settings.Instance.StaticFilesPath = "/Static";

            Assert.IsTrue(Settings.Instance.StaticFilesPath == "/Static/", "Missing leading and/or trailing slash");

            Settings.Instance.StaticFilesPath = "Static/";

            Assert.IsTrue(Settings.Instance.StaticFilesPath == "/Static/", "Missing leading and/or trailing slash");
        }

        [TestMethod]
        [TestCategory("Site settings")]
        public void VerifyStaticFilePathDefaultsToCorrectPath()
        {
            Settings.Instance.StaticFilesPath = "Static";

            Assert.IsFalse(string.IsNullOrEmpty(Settings.Instance.StaticFilesPath), "Unable to set static file path");

            Settings.Instance.StaticFilesPath = null;

            Assert.IsTrue(Settings.Instance.StaticFilesPath=="/Templates/", "Default static file path was not '/Templates/'");
        }

        [TestMethod]
        [TestCategory("Site settings")]
        public void VerifyBooleanSiteSettingsCanBeSetAndRetrieved()
        {
            // Date folder sorting
            Settings.Instance.DisableDateFolderSorting = false;
            Assert.IsFalse(Settings.Instance.DisableDateFolderSorting, "Unable to set 'Disable date folder sorting' to 'false'");
            Settings.Instance.DisableDateFolderSorting = true;
            Assert.IsTrue(Settings.Instance.DisableDateFolderSorting, "Unable to set 'Disable date folder sorting' to 'true'");

            // JavaScript links
            Settings.Instance.DisableJavaScriptLinks = false;
            Assert.IsFalse(Settings.Instance.DisableJavaScriptLinks, "Unable to set 'Disable JavaScript links' to 'false'");
            Settings.Instance.DisableJavaScriptLinks = true;
            Assert.IsTrue(Settings.Instance.DisableJavaScriptLinks, "Unable to set 'Disable JavaScript links' to 'true'");

            // Stylesheet links
            Settings.Instance.DisableStylesheetLinks = false;
            Assert.IsFalse(Settings.Instance.DisableStylesheetLinks, "Unable to set 'Disable stylesheet links' to 'false'");
            Settings.Instance.DisableStylesheetLinks = true;
            Assert.IsTrue(Settings.Instance.DisableStylesheetLinks, "Unable to set 'Disable stylesheet links' to 'true'");
        }


    }
}
